
#include "triangulo.h"

Triangulo::Triangulo( Vector *v1, Vector *v2, Vector *v3, Color *cor, double kAmbiente, double kDifusa, double kEspecular, int nShing)
: Object(cor,NULL,kAmbiente,kDifusa,kEspecular,nShing){
	this->vertice1 = v1;
	this->vertice2 = v2;
	this->vertice3 = v3;
}

Triangulo::Triangulo( Vector *v1, Vector *v2, Vector *v3)
: Object(){
	this->vertice1 = v1;
	this->vertice2 = v2;
	this->vertice3 = v3;
}

Vector* Triangulo::vetorNormal(Ray *raio){
	return this->vetorNormal();
}

Vector* Triangulo::vetorNormal(){
	// calcula os vetores que determinam o plano
	Vector* p1 = this->vertice2->subtracao(this->vertice1);
	Vector* p2 = this->vertice3->subtracao(this->vertice1);
	Vector* normal = p1->produtoVetorial(p2);
	return normal->vetorUnitario();
}

bool Triangulo::testarColisao(Ray *raio){
	/*double t = 0 , vn = 0, a = 0, b = 0, b1, b2, c1, c2, c3, c4;
	Vector *p; // ponto de intercecsao com o plano do triangulo 
	Vector *po = raio->getPosicao(); // posicao inicial do raio
	Vector *v = raio->getDirecao(); // direcao do raio
	Vector *n = this->vetorNormal(); // vetor normal ao plano do triangulo 

	Vector* p1 = this->vertice2->subtracao(this->vertice1); // vetores que determinam o plano (p1 , p2)
	Vector* p2 = this->vertice3->subtracao(this->vertice1); // 
	
	vn = v->produtoEscalar(n);
	if ( vn != 0){
		Vector *aux = this->vertice1->subtracao(po); // (A - Po)
		t = (aux->produtoEscalar(n)) / (vn); // (A - Po)* N / (V * N)
		p = po->soma(v->multiplicacao(t)); // P = Po + tV
		
		p = p->subtracao(this->vertice1);
		
		// resolve P = a*P1 + b*P2 , encontrando a e b
		b1 = p->getCoord(0) + p->getCoord(1);
		b2 = p->getCoord(1) + p->getCoord(2);
		
		c1 = p1->getCoord(0) + p1->getCoord(1);
		c2 = p1->getCoord(1) + p1->getCoord(2);
		
		c3 = p2->getCoord(0) + p2->getCoord(1);
		c4 = p2->getCoord(1) + p2->getCoord(2);
		
		a = (b1 * c4 - b2 * c3) / (c1 * c4 - c2 * c3);
		b = (c1 * b2 - c2 * b1) / (c1 * c4 - c2 * c3);

		if ((a >= 0) && (a <= 1) && (b >= 0) && (b <= 1) && ((a+b) <= 1)) {
			return true;
		} else {
			return false;
		} 
	} else {
		return false;
	}*/
	//este objeto deve ser testado para colisao
	return true;
}

Intersect* Triangulo::intersecsao(Ray *raio){

	double t = 0 , vn = 0, a = 0, b = 0, b1, b2, c1, c2, c3, c4;
	Vector *p; // ponto de intercecsao com o plano do triangulo 
	Vector *po = raio->getPosicao(); // posicao inicial do raio
	Vector *v = raio->direcao->vetorUnitario(); // direcao do raio
	Vector *n = this->vetorNormal(raio); // vetor normal ao plano do triangulo 

	Vector* p1 = this->vertice2->subtracao(this->vertice1); // vetores que determinam o plano (p1 , p2)
	Vector* p2 = this->vertice3->subtracao(this->vertice1); // 
	Vector* p3;

	vn = v->produtoEscalar(n);
	if ( vn != 0){
		Vector *aux = this->vertice1->subtracao(po); // (A - Po)
		t = (aux->produtoEscalar(n)) / (vn); // (A - Po)* N / (V * N)
		p = po->soma(v->multiplicacao(t)); // P = Po + tV
		
		// transformar para o plano do triangulo
		p3 = p->subtracao(this->vertice1);
		
		// resolve P = a*P1 + b*P2 , encontrando a e b
		b1 = p3->getCoord(0) + p3->getCoord(1);
		b2 = p3->getCoord(1) + p3->getCoord(2);
		
		c1 = p1->getCoord(0) + p1->getCoord(1);
		c2 = p1->getCoord(1) + p1->getCoord(2);
		
		c3 = p2->getCoord(0) + p2->getCoord(1);
		c4 = p2->getCoord(1) + p2->getCoord(2);
		
		a = (b1 * c4 - b2 * c3) / (c1 * c4 - c2 * c3);
		b = (c1 * b2 - c2 * b1) / (c1 * c4 - c2 * c3);

		if ((a >= 0) && (a <= 1) && (b >= 0) && (b <= 1) && ((a+b) <= 1)) {
			return (new Intersect( p, n, t));
		} else {
			return NULL;
		} 
	} else {
		return NULL;
	}
}
